{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## 2.4 微积分\n",
    "在深度学习中，我们“训练”模型，不断更新它们，使它们在看到越来越多的数据时变得越来越好。 通常情况下，变得更好意味着最小化一个损失函数（loss function）， 即一个衡量“模型有多糟糕”这个问题的分数。 最终，我们真正关心的是生成一个模型，它能够在从未见过的数据上表现良好。 但“训练”模型只能将模型与我们实际能看到的数据相拟合。 因此，我们可以将拟合模型的任务分解为两个关键问题：\n",
    "\n",
    "- 优化（optimization）：用模型拟合观测数据的过程；\n",
    "- 泛化（generalization）：数学原理和实践者的智慧，能够指导我们生成出有效性超出用于训练的数据集本身的模型\n",
    "\n",
    "### 2.4.1 导数和微分\n",
    "我们首先讨论导数的计算，这是几乎所有深度学习优化算法的关键步骤。 在深度学习中，我们通常选择对于模型参数可微的损失函数。 简而言之，对于每个参数， 如果我们把这个参数增加或减少一个无穷小的量，可以知道损失会以多快的速度增加或减少"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "h=0.10000, numerical limit=2.30000\n",
      "h=0.01000, numerical limit=2.03000\n",
      "h=0.00100, numerical limit=2.00300\n",
      "h=0.00010, numerical limit=2.00030\n",
      "h=0.00001, numerical limit=2.00003\n"
     ]
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "import numpy as np\n",
    "from matplotlib_inline import backend_inline\n",
    "import torch\n",
    "\n",
    "\n",
    "def f(x):\n",
    "    return 3 * x ** 2 - 4 * x\n",
    "\n",
    "\n",
    "def numerical_lim(f, x, h):\n",
    "    return (f(x + h) - f(x)) / h\n",
    "\n",
    "h = 0.1\n",
    "for i in range(5):\n",
    "    print(f'h={h:.5f}, numerical limit={numerical_lim(f, 1, h):.5f}')\n",
    "    h *= 0.1"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 2.4.2 偏导数\n",
    "高等数学基本知识\n",
    "\n",
    "### 2.4.3 梯度\n",
    "我们可以连结一个多元函数对其所有变量的偏导数，以得到该函数的梯度（gradient）向量。 具体而言，设函数$f: \\mathbb{R}^n \\rightarrow  \\mathbb{R}$的输入是一个$n$维向量，并且输出是一个标量。 函数$f(\\mathbf{x})$相对于$\\mathbf{x}$的梯度是一个包含$n$个偏导数的向量:\n",
    "$$ \\nabla_xf(\\mathbf{x}) = [\\frac{\\partial f(\\mathbf{x})}{\\partial x_1},...,\\frac{\\partial f(\\mathbf{x})}{\\partial x_n} ]^{\\top }$$\n",
    "\n",
    "其中$ \\nabla_xf(\\mathbf{x})$通常在没有歧义时被$ \\nabla f(\\mathbf{x})$取代。\n",
    "假设$\\mathbf{x}$为$n$维向量，在微分多元函数时经常使用以下规则:\n",
    "- 对于所有$\\mathrm{A} \\in \\mathbb{R}^{mn}$，都有$\\nabla_x \\mathrm{A}\\mathbf{x}=\\mathbf{A}^{\\top}$\n",
    "- 对于所有$\\mathrm{A} \\in \\mathbb{R}^{mn}$，都有$\\nabla_x \\mathbf{x}^{\\top}\\mathrm{A}=\\mathbf{A}$\n",
    "- 对于所有$\\mathrm{A} \\in \\mathbb{R}^{mn}$，都有$\\nabla_x \\mathbf{x}^{\\top}\\mathrm{A}\\mathbf{x}=(\\mathbf{A} + \\mathbf{A}^{\\top})\\mathbf{x}$\n",
    "- $\\nabla_x ||\\mathbf{x}||^{2}=\\nabla_x \\mathbf{x}^{\\top}\\mathbf{x} = 2\\mathbf{x}$\n",
    "\n",
    "\n",
    "同样，对于任何矩阵$\\mathrm{X}$，都有$ \\nabla_x ||\\mathrm{X}||_{\\mathrm{F}}^{2} = 2\\mathrm{X}$。 正如我们之后将看到的，梯度对于设计深度学习中的优化算法有很大用处。\n",
    "\n",
    "\n",
    "### 链式法则\n",
    "高等数学基本知识"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "name": "ml",
   "language": "python",
   "display_name": "ml"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}